#include <iostream>

using namespace std;

enum CompareTy
{
	CompareTy_Less,
	CompareTy_Greater,
	CompareTy_Equal,
	CompareTy_Unordered,
};

class A
{
public:
	virtual auto operator<=>(const A& other) const->CompareTy = 0;
};

class B : public A
{
	int _i = 0;

public:
	B(int i) { _i = i; }
	auto operator<=>(const A& other) const->CompareTy override
	{
		auto pB = dynamic_cast<const B*>(&other);
		if (!pB)
			return CompareTy_Unordered;

		auto& b = *pB;
		if (_i == b._i)
			return CompareTy_Equal;
		else if (_i < b._i)
			return CompareTy_Less;
		else
			return CompareTy_Greater;
	}
};

class C : public A
{
	int _i = 0;

public:
	C(int i) { _i = i; }
	auto operator<=>(const A& other) const->CompareTy override
	{
		auto pB = dynamic_cast<const C*>(&other);
		if (!pB)
			return CompareTy_Unordered;

		auto& b = *pB;
		if (_i == b._i)
			return CompareTy_Equal;
		else if (_i < b._i)
			return CompareTy_Less;
		else
			return CompareTy_Greater;
	}
};

void f(const A& lhs, const A& rhs)
{
	switch (lhs <=> rhs)
	{
	case CompareTy_Less:
		cout << "Less";
		break;
	case CompareTy_Greater:
		cout << "Greater";
		break;
	case CompareTy_Equal:
		cout << "Equal";
		break;
	case CompareTy_Unordered:
		cout << "Unordered";
		break;
	default:
		cout << "None";
		break;
	}
}


int main()
{
	f(B{ 1 }, B{ 2 });
	f(B{ 1 }, C{ 2 });


	return 0;
}